<p>Objects which are pooled and potentially reused should not be used for synchronization. If they are, it can cause unrelated threads to deadlock
with unhelpful stacktraces. Specifically, <code>String</code> literals, and boxed primitives such as Integers should not be used as lock objects
because they are pooled and reused. The story is even worse for <code>Boolean</code> objects, because there could possibly be only two instances of
<code>Boolean</code>, <code>Boolean.TRUE</code> and <code>Boolean.FALSE</code> and every class that uses a Boolean will be referring to one of the
two.</p>
<p>Here is the list of types which shouldn’t be used for synchronization:</p>
<ul>
  <li> The primitive wrapper classes in java.lang; </li>
  <li> The class java.lang.Runtime.Version; </li>
  <li> The "optional" classes in java.util: Optional, OptionalInt, OptionalLong, and OptionalDouble; </li>
  <li> Many classes in the java.time API: Instant, LocalDate, LocalTime, LocalDateTime, ZonedDateTime, ZoneId, OffsetTime, OffsetDateTime, ZoneOffset,
  Duration, Period, Year, YearMonth, and MonthDay, and, in java.time.chrono: MinguoDate, HijrahDate, JapaneseDate, and ThaiBuddhistDate; </li>
  <li> The interface java.lang.ProcessHandle and its implementation classes; </li>
  <li> The implementation classes of the collection factories in java.util: List.of, List.copyOf, Set.of, Set.copyOf, Map.of, Map.copyOf,
  Map.ofEntries, and Map.entry. </li>
</ul>
<h2>Noncompliant Code Example</h2>
<pre>
private static final Boolean bLock = Boolean.FALSE;
private static final Integer iLock = Integer.valueOf(0);
private static final String sLock = "LOCK";
private static final List&lt;String&gt; listLock = List.of("a", "b", "c", "d");

public void doSomething() {

  synchronized(bLock) {  // Noncompliant
    // ...
  }
  synchronized(iLock) {  // Noncompliant
    // ...
  }
  synchronized(sLock) {  // Noncompliant
    // ...
  }
  synchronized(listLock) {  // Noncompliant
    // ...
  }
</pre>
<h2>Compliant Solution</h2>
<pre>
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
private static final Object lock3 = new Object();
private static final Object lock4 = new Object();

public void doSomething() {

  synchronized(lock1) {
    // ...
  }
  synchronized(lock2) {
    // ...
  }
  synchronized(lock3) {
    // ...
  }
  synchronized(lock4) {
    // ...
  }
</pre>
<h2>See</h2>
<ul>
  <li> <a href="https://wiki.sei.cmu.edu/confluence/x/1zdGBQ">CERT, LCK01-J.</a> - Do not synchronize on objects that may be reused </li>
  <li> <a href="https://openjdk.java.net/jeps/390">JEP-390.</a> - JEP 390: Warnings for Value-Based Classes </li>
</ul>

